Spring JDBC এবং ResultSetExtractor

Java Technologies - স্প্রিং জেডিবিসি (Spring JDBC)
85
85

Spring JDBC-তে ResultSetExtractor একটি ইন্টারফেস যা JDBC ResultSet থেকে ডেটা পড়তে এবং এটি Java অবজেক্টে রূপান্তর করতে ব্যবহৃত হয়। যখন একাধিক রেকর্ড বা জটিল ডেটা রিটার্ন করতে হয়, তখন ResultSetExtractor অনেক সুবিধা প্রদান করে। এটি সাধারণত যখন আপনি একাধিক রেকর্ড থেকে ডেটা একত্রিত করতে চান বা একটি কাস্টম অবজেক্ট তৈরি করতে চান, তখন ব্যবহৃত হয়।

ResultSetExtractor এর ব্যবহার

Spring JDBC-তে ResultSetExtractor ব্যবহার করলে আমরা সহজেই একটি ResultSet থেকে ডেটা বের করে একটি কাস্টম অবজেক্টে রূপান্তর করতে পারি। এটি যখন একাধিক রেকর্ড একত্রিত করতে বা একাধিক টেবিল থেকে ডেটা নিয়ে কাজ করতে হয়, তখন বেশি কার্যকর।

ResultSetExtractor ইন্টারফেসের একটি মেথড আছে:

  • extractData(ResultSet rs): এটি একটি ResultSet আর্গুমেন্ট হিসেবে নেয় এবং একটি অবজেক্ট রিটার্ন করে।

উদাহরণ: Spring JDBC এবং ResultSetExtractor

ধরা যাক, আমাদের একটি Employee টেবিল আছে যার মধ্যে id, name, salary ফিল্ড রয়েছে। আমরা ResultSetExtractor ব্যবহার করে Employee অবজেক্টের একটি লিস্ট তৈরি করব।

১. Maven ডিপেনডেন্সি:

প্রথমে, Spring JDBC ডিপেনডেন্সি যুক্ত করুন (যদি না থাকে)।

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.3.24</version> <!-- সর্বশেষ সংস্করণ নিশ্চিত করতে Maven Repository থেকে চেক করুন -->
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.24</version>
</dependency>

২. Employee এবং EmployeeRowMapper ক্লাস:

প্রথমে, আমরা Employee ক্লাস তৈরি করি যা ডেটাবেসের Employee টেবিলের রেকর্ডের প্রতিনিধিত্ব করবে।

public class Employee {
    private int id;
    private String name;
    private double salary;

    // Getter এবং Setter মেথড
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

৩. ResultSetExtractor ক্লাস:

এখন আমরা ResultSetExtractor ইন্টারফেস ইমপ্লিমেন্ট করে একটি কাস্টম ক্লাস তৈরি করব যা ResultSet থেকে Employee অবজেক্টের লিস্ট রিটার্ন করবে।

import org.springframework.jdbc.core.ResultSetExtractor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class EmployeeResultSetExtractor implements ResultSetExtractor<List<Employee>> {

    @Override
    public List<Employee> extractData(ResultSet rs) throws SQLException {
        List<Employee> employeeList = new ArrayList<>();
        
        while (rs.next()) {
            Employee employee = new Employee();
            employee.setId(rs.getInt("id"));
            employee.setName(rs.getString("name"));
            employee.setSalary(rs.getDouble("salary"));
            employeeList.add(employee);
        }

        return employeeList;
    }
}

এখানে, extractData() মেথডটি ResultSet থেকে Employee অবজেক্টের একটি লিস্ট তৈরি করছে। ResultSet থেকে একে একে প্রতিটি রেকর্ড নিয়ে, একটি Employee অবজেক্ট তৈরি করা হচ্ছে এবং সেটিকে employeeList তে যুক্ত করা হচ্ছে।

৪. JdbcTemplate ব্যবহার করে Query চালানো:

এখন, আমরা JdbcTemplate ব্যবহার করে SQL কোয়েরি চালিয়ে ResultSetExtractor থেকে Employee লিস্ট বের করব।

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;

@Component
public class EmployeeDAO {

    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public EmployeeDAO(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    // সমস্ত Employee পড়ার জন্য
    public List<Employee> getAllEmployees() {
        String sql = "SELECT * FROM Employee";
        return jdbcTemplate.query(sql, new EmployeeResultSetExtractor());
    }
}

এখানে, jdbcTemplate.query() মেথডে SQL কোয়েরি এবং ResultSetExtractor পাস করা হয়েছে, যা ডেটাবেস থেকে Employee রেকর্ডগুলি বের করে এবং List<Employee> রিটার্ন করে।

৫. Main ক্লাস:

এখন, Main ক্লাসে আমরা EmployeeDAO ব্যবহার করে ডেটাবেস থেকে Employee রেকর্ডগুলো পড়ব।

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        // Spring কনটেক্সট ইনিশিয়ালাইজ করা
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DataSourceConfig.class);

        EmployeeDAO employeeDAO = context.getBean(EmployeeDAO.class);

        // সমস্ত Employee পড়া
        List<Employee> employees = employeeDAO.getAllEmployees();
        
        // Employee রেকর্ড প্রিন্ট করা
        employees.forEach(employee -> System.out.println(employee.getId() + " - " + employee.getName() + " - " + employee.getSalary()));

        context.close();
    }
}

৬. DataSource কনফিগারেশন:

এটি আপনার DataSource কনফিগারেশন, যেমন HikariCP বা Tomcat Connection Pool দ্বারা কনফিগার করা হবে। আগের উদাহরণে দেখানো কনফিগারেশনটি ব্যবহার করুন।


ResultSetExtractor কেন ব্যবহৃত হয়?

  • Multiple Rows/Records: যখন ডেটাবেস থেকে একাধিক রেকর্ড বের করতে হয়, তখন ResultSetExtractor খুব কার্যকর। এটি একাধিক রেকর্ড থেকে ডেটা সংগ্রহ করতে সাহায্য করে।
  • Custom Mapping: যখন একটি কাস্টম অবজেক্টে ডেটা রূপান্তর করতে হয়, যেমন একাধিক টেবিলের ডেটা একত্রিত করা, তখন ResultSetExtractor একটি ভাল পছন্দ।
  • Complex Queries: যখন SQL কোয়েরি জটিল হয়, যেমন একাধিক JOIN করা, তখন ResultSetExtractor ব্যবহার করা সহজ এবং সুবিধাজনক।

উপসংহার:

  • ResultSetExtractor Spring JDBC-তে ডেটা রূপান্তরের একটি শক্তিশালী উপায়।
  • এটি একাধিক রেকর্ড বা জটিল ডেটা সঠিকভাবে বের করতে সাহায্য করে।
  • JdbcTemplate.query() মেথডের মাধ্যমে ResultSetExtractor ব্যবহার করা হয়, যা ResultSet থেকে ডেটা বের করে কাস্টম অবজেক্টে রূপান্তর করে।
Content added By

ResultSetExtractor কি এবং এর প্রয়োজনীয়তা

72
72

ResultSetExtractor Spring JDBC-এর একটি ইন্টারফেস, যা ডেটাবেসের একটি ResultSet থেকে কাস্টম অবজেক্ট তৈরি করতে ব্যবহার করা হয়। এটি জটিল এবং কাস্টমাইজড ডেটা প্রসেসিংয়ের জন্য ব্যবহার করা হয়, যেখানে একটি RowMapper যথেষ্ট নয়।


ResultSetExtractor ইন্টারফেসের সিগনেচার:

public interface ResultSetExtractor<T> {
    T extractData(ResultSet rs) throws SQLException, DataAccessException;
}
  • extractData():
    • এই মেথডটি ডেটাবেস থেকে প্রাপ্ত সম্পূর্ণ ResultSet প্রসেস করতে ব্যবহৃত হয়।
    • এটি একটি জাভা অবজেক্ট রিটার্ন করে, যা ডেটা সংগ্রহ বা প্রসেসিংয়ের প্রয়োজনীয় কাজ সম্পন্ন করে।

ResultSetExtractor কেন প্রয়োজন?

  1. কাস্টম লজিক প্রয়োগ:
    • যখন ডেটার উপর নির্দিষ্ট লজিক প্রয়োগ করতে হয়, যেমন নেস্টেড ডেটা প্রসেস করা বা ডেটা গ্রুপিং করা।
  2. মাল্টিপল রো প্রসেসিং:
    • ডেটাবেস থেকে প্রাপ্ত একাধিক রো (row) একই সময়ে প্রসেস করতে হলে এটি দরকার।
  3. জটিল অবজেক্ট ম্যাপিং:
    • জটিল অবজেক্ট বা নেস্টেড অবজেক্ট তৈরি করতে ResultSetExtractor খুব কার্যকর।
  4. বিকল্প টু RowMapper:
    • RowMapper একবারে একটি রো প্রসেস করে, তবে ResultSetExtractor পুরো ResultSet একবারে প্রসেস করতে পারে।

ResultSetExtractor উদাহরণ:

ধরা যাক, আমাদের একটি টেবিল orders রয়েছে যেখানে অর্ডার এবং প্রোডাক্টের সম্পর্ক রয়েছে। আমরা একটি নেস্টেড অবজেক্ট তৈরি করতে চাই যেখানে প্রতিটি অর্ডারের জন্য প্রোডাক্ট লিস্ট থাকবে।


টেবিল: orders

order_idproduct_namequantity
1Laptop2
1Mouse5
2Keyboard3
2Monitor1

Order এবং Product ক্লাস:

import java.util.List;

public class Order {
    private int orderId;
    private List<Product> products;

    // Getters and Setters
    public int getOrderId() {
        return orderId;
    }
    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }
    public List<Product> getProducts() {
        return products;
    }
    public void setProducts(List<Product> products) {
        this.products = products;
    }
}

public class Product {
    private String productName;
    private int quantity;

    // Getters and Setters
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public int getQuantity() {
        return quantity;
    }
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
}

ResultSetExtractor ইমপ্লিমেন্টেশন:

import org.springframework.jdbc.core.ResultSetExtractor;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class OrderResultSetExtractor implements ResultSetExtractor<List<Order>> {
    @Override
    public List<Order> extractData(ResultSet rs) throws SQLException {
        Map<Integer, Order> orderMap = new HashMap<>();
        while (rs.next()) {
            int orderId = rs.getInt("order_id");
            Order order = orderMap.get(orderId);

            if (order == null) {
                order = new Order();
                order.setOrderId(orderId);
                order.setProducts(new ArrayList<>());
                orderMap.put(orderId, order);
            }

            Product product = new Product();
            product.setProductName(rs.getString("product_name"));
            product.setQuantity(rs.getInt("quantity"));

            order.getProducts().add(product);
        }
        return new ArrayList<>(orderMap.values());
    }
}

JdbcTemplate দিয়ে ResultSetExtractor ব্যবহার:

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import java.util.List;

public class ResultSetExtractorExample {
    public static void main(String[] args) {
        // DataSource Configuration
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/your_database");
        dataSource.setUsername("your_username");
        dataSource.setPassword("your_password");

        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

        String query = "SELECT order_id, product_name, quantity FROM orders";

        // Execute query with ResultSetExtractor
        List<Order> orders = jdbcTemplate.query(query, new OrderResultSetExtractor());

        // Print orders
        for (Order order : orders) {
            System.out.println("Order ID: " + order.getOrderId());
            for (Product product : order.getProducts()) {
                System.out.println("  Product: " + product.getProductName());
                System.out.println("  Quantity: " + product.getQuantity());
            }
        }
    }
}

আউটপুট:

Order ID: 1
  Product: Laptop
  Quantity: 2
  Product: Mouse
  Quantity: 5
Order ID: 2
  Product: Keyboard
  Quantity: 3
  Product: Monitor
  Quantity: 1

ResultSetExtractor এর সুবিধা:

  1. পূর্ণ ResultSet প্রসেসিং: পুরো ResultSet একবারে প্রসেস করা যায়।
  2. জটিল ডেটা স্ট্রাকচার: নেস্টেড বা গ্রুপড ডেটা তৈরি করতে কার্যকর।
  3. উচ্চতর কাস্টমাইজেশন: কাস্টম লজিক বা ফিল্টারিং সহজে প্রয়োগ করা যায়।

কোথায় ব্যবহার করবেন?

  • যখন জটিল ডেটা প্রসেসিং প্রয়োজন।
  • নেস্টেড অবজেক্ট তৈরি করতে হবে।
  • একাধিক রো থেকে গ্রুপ করা ডেটা প্রয়োজন।

ResultSetExtractor একটি শক্তিশালী ইন্টারফেস যা Spring JDBC-তে জটিল ডেটা ম্যাপিং সহজ করে।

Content added By

Custom ResultSetExtractor তৈরি করা

95
95

Spring JDBC-তে ResultSetExtractor একটি ইন্টারফেস, যা ডাটাবেসের ResultSet থেকে কাস্টম অবজেক্ট তৈরি করতে ব্যবহার করা হয়। এটি একাধিক রেকর্ড বা জটিল ডাটা স্ট্রাকচারকে ম্যানিপুলেট করার জন্য কার্যকর।

ResultSetExtractor ব্যবহার তখনই সুবিধাজনক, যখন:

  1. আপনাকে একাধিক টেবিল বা জটিল ডাটা স্ট্রাকচার থেকে ডেটা ম্যাপ করতে হবে।
  2. সাধারণ RowMapper যথেষ্ট না হয়।

ResultSetExtractor ইন্টারফেসের সিগনেচার:

@FunctionalInterface
public interface ResultSetExtractor<T> {
    T extractData(ResultSet rs) throws SQLException, DataAccessException;
}

Custom ResultSetExtractor তৈরির ধাপ

  1. ResultSetExtractor ইন্টারফেস ইমপ্লিমেন্ট করা।
  2. ResultSet থেকে ডেটা প্রসেস করা।
  3. JdbcTemplate এর query() মেথডে ResultSetExtractor ব্যবহার করা।

উদাহরণ

1. সাধারণ টেবিল থেকে ডেটা প্রসেস করা

ধরি, আমাদের একটি টেবিল রয়েছে:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100),
    age INT
);
Custom ResultSetExtractor:
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UserResultSetExtractor implements ResultSetExtractor<List<User>> {

    @Override
    public List<User> extractData(ResultSet rs) throws SQLException, DataAccessException {
        List<User> users = new ArrayList<>();

        while (rs.next()) {
            User user = new User();
            user.setId(rs.getInt("id"));
            user.setName(rs.getString("name"));
            user.setEmail(rs.getString("email"));
            user.setAge(rs.getInt("age"));
            users.add(user);
        }

        return users;
    }
}
JdbcTemplate ব্যবহার:
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List<User> getAllUsers() {
        String sql = "SELECT * FROM users";
        return jdbcTemplate.query(sql, new UserResultSetExtractor());
    }
}
User ক্লাস:
public class User {
    private int id;
    private String name;
    private String email;
    private int age;

    // Getters and Setters
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", email=" + email + ", age=" + age + "]";
    }
}

2. জটিল স্ট্রাকচার থেকে ডেটা প্রসেস করা

ধরি, আমাদের দুটি টেবিল রয়েছে:

  • users টেবিল:

    CREATE TABLE users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(100)
    );
    
  • orders টেবিল:

    CREATE TABLE orders (
        id INT AUTO_INCREMENT PRIMARY KEY,
        user_id INT,
        order_details VARCHAR(255),
        FOREIGN KEY (user_id) REFERENCES users(id)
    );
    
Custom ResultSetExtractor:
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserOrderResultSetExtractor implements ResultSetExtractor<Map<String, List<String>>> {

    @Override
    public Map<String, List<String>> extractData(ResultSet rs) throws SQLException, DataAccessException {
        Map<String, List<String>> userOrders = new HashMap<>();

        while (rs.next()) {
            String userName = rs.getString("name");
            String orderDetails = rs.getString("order_details");

            userOrders.computeIfAbsent(userName, k -> new ArrayList<>()).add(orderDetails);
        }

        return userOrders;
    }
}
JdbcTemplate ব্যবহার:
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class OrderService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public Map<String, List<String>> getUserOrders() {
        String sql = "SELECT u.name, o.order_details FROM users u JOIN orders o ON u.id = o.user_id";
        return jdbcTemplate.query(sql, new UserOrderResultSetExtractor());
    }
}

ResultSetExtractor বনাম RowMapper

ফিচারResultSetExtractorRowMapper
ব্যবহারজটিল বা কাস্টম ডেটা স্ট্রাকচার প্রসেস করার জন্য উপযোগী।প্রতিটি রেকর্ড সহজভাবে একটি অবজেক্টে ম্যাপ করতে।
রিটার্ন টাইপএকাধিক রেকর্ড বা জটিল ডেটা স্ট্রাকচার রিটার্ন করতে পারে।সাধারণত একটি রেকর্ডের অবজেক্ট রিটার্ন করে।
প্রসেসিংResultSet সম্পূর্ণ প্রসেস করার স্বাধীনতা দেয়।প্রতিটি রেকর্ড প্রসেস করে।

উপসংহার

Spring JDBC-এর ResultSetExtractor জটিল ডেটা প্রসেস করার জন্য একটি অত্যন্ত কার্যকর টুল। যদি আপনার ডাটাবেস স্ট্রাকচার জটিল হয় বা একাধিক টেবিলের সাথে কাজ করতে হয়, তাহলে ResultSetExtractor ব্যবহার করে আপনি সহজেই ডেটা প্রসেস করতে পারেন।

Content added By

Complex Queries এর জন্য ResultSetExtractor ব্যবহার

103
103

ResultSetExtractor Spring JDBC-তে ব্যবহৃত একটি ইন্টারফেস, যা জটিল SQL কুয়েরি থেকে ডেটা প্রসেস এবং রিটার্ন করার জন্য ব্যবহৃত হয়। এটি এমন ক্ষেত্রে উপযোগী যেখানে ডেটাবেস থেকে রিলেশনাল ডেটা প্রসেস করতে হয় এবং একাধিক টেবিল থেকে ডেটা নিয়ে আসা হয়।


ResultSetExtractor কেন প্রয়োজন?

  1. কাস্টম ডেটা ম্যাপিং:
    • যখন ডেটা অবজেক্টে রূপান্তর করতে জটিল লজিক প্রয়োজন।
  2. নেস্টেড ডেটা প্রসেসিং:
    • নেস্টেড রিলেশনাল ডেটা (যেমন Parent-Child সম্পর্ক) প্রসেস করতে।
  3. ফ্ল্যাট ResultSet এর বিকল্প:
    • যখন একাধিক রেকর্ড বা নেস্টেড ডেটা কাঠামো তৈরি করতে হয়।

ResultSetExtractor এর ব্যবহার

১. ResultSetExtractor ইন্টারফেসের মেথড

  • T extractData(ResultSet rs) throws SQLException, DataAccessException
    • ResultSet থেকে ডেটা প্রসেস করে একটি কাস্টম অবজেক্ট বা ডেটা কাঠামো রিটার্ন করে।

ResultSetExtractor ব্যবহার করার ধাপ

১. ডেটা মডেল তৈরি করা

public class Order {
    private int id;
    private String customerName;
    private List<OrderItem> items;

    // Getters, Setters, and Constructor
}

public class OrderItem {
    private int id;
    private String productName;
    private int quantity;

    // Getters, Setters, and Constructor
}

২. SQL কুয়েরি লিখুন

SELECT o.id AS order_id, o.customer_name, 
       i.id AS item_id, i.product_name, i.quantity
FROM orders o
JOIN order_items i ON o.id = i.order_id
WHERE o.id = ?;

৩. ResultSetExtractor ইম্প্লিমেন্টেশন

import org.springframework.jdbc.core.ResultSetExtractor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class OrderResultSetExtractor implements ResultSetExtractor<Order> {

    @Override
    public Order extractData(ResultSet rs) throws SQLException {
        Order order = null;
        List<OrderItem> items = new ArrayList<>();

        while (rs.next()) {
            if (order == null) {
                // প্রথম রেকর্ডে অর্ডার অবজেক্ট তৈরি
                order = new Order(
                    rs.getInt("order_id"),
                    rs.getString("customer_name"),
                    items
                );
            }

            // প্রতিটি অর্ডার আইটেম প্রসেস
            OrderItem item = new OrderItem(
                rs.getInt("item_id"),
                rs.getString("product_name"),
                rs.getInt("quantity")
            );
            items.add(item);
        }
        return order;
    }
}

৪. JdbcTemplate ব্যবহার করে কুয়েরি চালানো

import org.springframework.jdbc.core.JdbcTemplate;

public class OrderRepository {

    private final JdbcTemplate jdbcTemplate;

    public OrderRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public Order getOrderById(int orderId) {
        String sql = "SELECT o.id AS order_id, o.customer_name, " +
                     "i.id AS item_id, i.product_name, i.quantity " +
                     "FROM orders o " +
                     "JOIN order_items i ON o.id = i.order_id " +
                     "WHERE o.id = ?";
        return jdbcTemplate.query(sql, new OrderResultSetExtractor(), orderId);
    }
}

৫. ক্লায়েন্ট কোড

public class MainApp {
    public static void main(String[] args) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(/* DataSource Configuration */);
        OrderRepository orderRepository = new OrderRepository(jdbcTemplate);

        Order order = orderRepository.getOrderById(1);
        System.out.println("Order ID: " + order.getId());
        System.out.println("Customer Name: " + order.getCustomerName());
        System.out.println("Items:");
        order.getItems().forEach(item -> 
            System.out.println(item.getProductName() + " - Quantity: " + item.getQuantity())
        );
    }
}

ResultSetExtractor এর সুবিধা

  1. জটিল ডেটা প্রসেসিং:
    • নেস্টেড বা মাল্টি-টেবিল ডেটা কুয়েরি সহজে প্রসেস করা যায়।
  2. কাস্টম ডেটা স্ট্রাকচার:
    • একাধিক অবজেক্টে ডেটা ম্যাপ করার সুবিধা।
  3. একাধিক রেকর্ড হ্যান্ডলিং:
    • একাধিক রেকর্ড বা সম্পর্কযুক্ত ডেটা প্রসেস করা সহজ।

ResultSetExtractor এর সীমাবদ্ধতা

  1. ম্যাপিং লজিক হাতে কোড করতে হয়:
    • এটি ম্যানুয়াল কাজ বাড়াতে পারে।
  2. কমপ্লেক্সিটি:
    • খুব জটিল কুয়েরি থাকলে ম্যাপিং লজিক বোঝা কঠিন হতে পারে।

ResultSetExtractor বনাম RowMapper

FeatureResultSetExtractorRowMapper
ব্যবহারজটিল ডেটা প্রসেসিংসাধারণ ফ্ল্যাট ডেটা প্রসেসিং
রিটার্ন টাইপকাস্টম অবজেক্ট বা স্ট্রাকচারএকক অবজেক্ট বা রেকর্ড লিস্ট
কাস্টম লজিককাস্টম লজিক লিখা সহজসীমিত কাস্টম লজিক
নেস্টেড ডেটানেস্টেড ডেটা ম্যাপিং সহজজটিল ম্যাপিং সম্ভব নয়

উপসংহার

Spring JDBC-তে ResultSetExtractor জটিল কুয়েরি থেকে ডেটা প্রসেস এবং কাস্টম অবজেক্ট তৈরি করার জন্য একটি শক্তিশালী এবং নমনীয় পদ্ধতি। এটি বিশেষত নেস্টেড বা সম্পর্কযুক্ত ডেটার ক্ষেত্রে কার্যকর। তবে সাধারণ কাজের জন্য RowMapper সহজতর এবং উপযোগী। ResultSetExtractor ব্যবহার করে ডেটা প্রসেসিং সম্পূর্ণরূপে ডেভেলপারের নিয়ন্ত্রণে থাকে, যা বৃহৎ এবং জটিল অ্যাপ্লিকেশনে সহায়ক।

Content added By

উদাহরণ সহ ResultSetExtractor এর ব্যবহার

60
60

Spring JDBC-তে ResultSetExtractor একটি ইন্টারফেস, যা জটিল ডাটাবেস অপারেশনের জন্য ব্যবহার করা হয়। এটি ডাটাবেস থেকে রিট্রাইভ করা ResultSet এর উপর কাস্টম প্রক্রিয়াকরণ করার জন্য একটি সুবিধাজনক পদ্ধতি সরবরাহ করে।


ResultSetExtractor কী?

  • ResultSetExtractor একটি ফাংশনাল ইন্টারফেস যা শুধুমাত্র একটি মেথড সরবরাহ করে:

    T extractData(ResultSet rs) throws SQLException, DataAccessException;
    
  • এটি একটি সম্পূর্ণ ResultSet নেয় এবং এটি প্রক্রিয়াকরণ করে একটি অবজেক্ট রিটার্ন করে।
  • এটি যখন ডাটাবেসের একাধিক রেকর্ড নিয়ে কাজ করতে হয় এবং ডাটা ম্যানিপুলেশন প্রয়োজন, তখন ব্যবহৃত হয়।

ResultSetExtractor ব্যবহার করার সুবিধা

  1. কাস্টম ডাটা প্রসেসিং: একাধিক রেকর্ড বা জটিল ডাটা প্রসেসিংয়ের জন্য আদর্শ।
  2. লুজলি-কাপল্ড ডিজাইন: Spring এর JdbcTemplate API এর সাথে সহজেই ইন্টিগ্রেটেড।
  3. জটিল লজিক ইমপ্লিমেন্ট করা সহজ: যখন RowMapper যথেষ্ট নয়, তখন ResultSetExtractor ব্যবহৃত হয়।

ResultSetExtractor এর ব্যবহার উদাহরণ

উদাহরণ ১: সিম্পল কাস্টম ডাটা প্রসেসিং

ধরা যাক আমাদের একটি employees টেবিল রয়েছে:

CREATE TABLE employees (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    department VARCHAR(50),
    salary DECIMAL(10, 2)
);

আমরা ResultSetExtractor ব্যবহার করে একটি তালিকা তৈরি করব যেখানে প্রত্যেক ডিপার্টমেন্টের অধীনে কাজ করা সকল কর্মচারী থাকবে।

কোড:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.stereotype.Service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class EmployeeService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public Map<String, List<String>> getEmployeesByDepartment() {
        String sql = "SELECT name, department FROM employees";

        return jdbcTemplate.query(sql, new ResultSetExtractor<Map<String, List<String>>>() {
            @Override
            public Map<String, List<String>> extractData(ResultSet rs) throws SQLException {
                Map<String, List<String>> departmentMap = new HashMap<>();

                while (rs.next()) {
                    String department = rs.getString("department");
                    String name = rs.getString("name");

                    departmentMap.putIfAbsent(department, new ArrayList<>());
                    departmentMap.get(department).add(name);
                }

                return departmentMap;
            }
        });
    }
}

ফলাফল:
যদি টেবিলের ডাটা এই রকম হয়:

INSERT INTO employees (id, name, department, salary) VALUES (1, 'John Doe', 'HR', 50000);
INSERT INTO employees (id, name, department, salary) VALUES (2, 'Jane Smith', 'IT', 60000);
INSERT INTO employees (id, name, department, salary) VALUES (3, 'Bob Johnson', 'HR', 45000);

তাহলে মেথডটি রিটার্ন করবে:

{
    "HR": ["John Doe", "Bob Johnson"],
    "IT": ["Jane Smith"]
}

উদাহরণ ২: জটিল ডাটা প্রসেসিং

ধরা যাক, আপনি প্রতিটি ডিপার্টমেন্টের জন্য টোটাল সেলারি এবং কর্মচারীদের সংখ্যা খুঁজছেন।

কোড:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.stereotype.Service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

@Service
public class DepartmentStatsService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public Map<String, Map<String, Object>> getDepartmentStats() {
        String sql = "SELECT department, COUNT(*) AS employee_count, SUM(salary) AS total_salary FROM employees GROUP BY department";

        return jdbcTemplate.query(sql, new ResultSetExtractor<Map<String, Map<String, Object>>>() {
            @Override
            public Map<String, Map<String, Object>> extractData(ResultSet rs) throws SQLException {
                Map<String, Map<String, Object>> statsMap = new HashMap<>();

                while (rs.next()) {
                    String department = rs.getString("department");
                    int employeeCount = rs.getInt("employee_count");
                    double totalSalary = rs.getDouble("total_salary");

                    Map<String, Object> stats = new HashMap<>();
                    stats.put("employee_count", employeeCount);
                    stats.put("total_salary", totalSalary);

                    statsMap.put(department, stats);
                }

                return statsMap;
            }
        });
    }
}

ফলাফল:
যদি টেবিলের ডাটা এই রকম হয়:

INSERT INTO employees (id, name, department, salary) VALUES (1, 'John Doe', 'HR', 50000);
INSERT INTO employees (id, name, department, salary) VALUES (2, 'Jane Smith', 'IT', 60000);
INSERT INTO employees (id, name, department, salary) VALUES (3, 'Bob Johnson', 'HR', 45000);

তাহলে মেথডটি রিটার্ন করবে:

{
    "HR": {
        "employee_count": 2,
        "total_salary": 95000.0
    },
    "IT": {
        "employee_count": 1,
        "total_salary": 60000.0
    }
}

ResultSetExtractor বনাম RowMapper

প্যারামিটারResultSetExtractorRowMapper
ব্যবহার ক্ষেত্রএকাধিক রেকর্ড থেকে জটিল প্রসেসিং প্রয়োজন।প্রতিটি রেকর্ডকে একটি অবজেক্টে ম্যাপ করা।
রিটার্ন টাইপকাস্টম ডাটা টাইপ রিটার্ন করে।একটি লিস্ট বা একক অবজেক্ট রিটার্ন করে।
লজিকের জটিলতাজটিল ডাটা প্রসেসিং সহজ।সাধারণ ডাটা ম্যাপিং-এর জন্য আদর্শ।

উপসংহার

Spring JDBC-তে ResultSetExtractor এমন পরিস্থিতিতে ব্যবহার করা হয় যেখানে একাধিক রেকর্ড বা জটিল ডাটা প্রসেসিং প্রয়োজন। এটি ডাটাবেস থেকে রিট্রাইভ করা ডাটার উপর সম্পূর্ণ কাস্টম প্রক্রিয়াকরণ করার স্বাধীনতা প্রদান করে। সহজ ডাটা ম্যাপিং-এর জন্য RowMapper যথেষ্ট হলেও, জটিল ডাটা লজিক ইমপ্লিমেন্ট করার জন্য ResultSetExtractor একটি শক্তিশালী টুল।

Content added By
টপ রেটেড অ্যাপ

স্যাট অ্যাকাডেমী অ্যাপ

আমাদের অল-ইন-ওয়ান মোবাইল অ্যাপের মাধ্যমে সীমাহীন শেখার সুযোগ উপভোগ করুন।

ভিডিও
লাইভ ক্লাস
এক্সাম
ডাউনলোড করুন
Promotion